﻿using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Core
{
    public static class ArrayExtension
    {
        public static T[] Reverse<T>(this T[] input) where T : struct
        {
            List<T> list = input.ToList();
            list.Reverse();
            return list.ToArray();
        }

        public static T[] Sort<T>(this T[] input) where T : struct
        {
            List<T> list = input.ToList();
            list.Sort();
            return list.ToArray();
        }

        public static T First<T>(this T[] input) where T : struct
        {
            return input[0];
        }

        public static T Last<T>(this T[] input) where T : struct
        {
            return input[input.Length - 1];
        }

        /// <summary>
        /// 提取数组中的一部分
        /// </summary>
        /// <typeparam name="T">所有的数值类型</typeparam>
        /// <param name="input">原始数组</param>
        /// <param name="start">从第几个开始，第一个从1开始</param>
        /// <param name="end">到第几个结束</param>
        /// <returns>提取的数组</returns>
        public static T[] Slice<T>(this T[] input, int? start = null, int? end = null) where T : struct
        {
            if (input == null || input.Length == 0) { return input; }

            int x = start ?? 1;
            int y = end ?? input.Length;

            // 如果x小于0，说明从数组尾部开始提取，计算出尾部的开始下标
            x = (x < 0) ? (input.Length - Math.Abs(x)) : (x - 1);
            // 如果x的绝对值大于数组长度，默认为数组长度
            x = x > input.Length ? (input.Length - 1) : x;
            // 如果y小于0，说明在数组头部结束，计算出头部的下标
            y = (y < 0) ? (input.Length - Math.Abs(y)) : (y - 1);
            // 如果y的绝对值大于数组长度，默认为数组长度
            y = y > input.Length ? (input.Length - 1) : y;

            List<T> output = new List<T>();
            if (x > y)
            {
                for (int i = x; i >= y; i--)
                {
                    if (i < 0 || i > (input.Length - 1)) { break; }
                    output.Add(input[i]);
                }
            }
            else
            {
                for (int i = x; i <= y; i++)
                {
                    if (i < 0 || i > (input.Length - 1)) { break; }
                    output.Add(input[i]);
                }
            }

            return output.ToArray();
        }

        public static string Join<T>(this T[] input, string separator = ",") where T : struct
        {
            string output = string.Empty;
            foreach (var item in input)
            {
                output += item.ToString() + separator;
            }

            return output.TrimEnd(separator.ToChar());
        }

        public static string Contact<T>(this T[] input) where T : struct
        {
            return Join(input).Remove(",");
        }

        public static string Join(this string[] input, string separator = ",")
        {
            string output = string.Empty;
            foreach (var item in input)
            {
                output += item.ToString() + separator;
            }

            return output.TrimEnd(separator.ToChar());
        }

        public static string Contact(this string[] input)
        {
            return Join(input).Remove(",");
        }
    }
}